#include "sessionfriendarea.h"
#include"debug.h"
#include"mainwidget.h"
#include<QStyleOption>
#include"mainwidget.h"

SessionFriendArea::SessionFriendArea() {
    // 1. 设置基础属性
    // ⼀定要添加这个设置, 否则⽆法正确显⽰.
    this->setWidgetResizable(true);
    // 设置滚动条宽度
    /* 滚动条上下箭头按钮样式 */

    //给QScrollArea和其垂直滚动条安装事件过滤器
    this->viewport()->installEventFilter(this);
    this->verticalScrollBar()->installEventFilter(this);

    // 为你的QWidget或QMainWindow设置样式表
    this->setStyleSheet(R"(
    QScrollBar:vertical {
        border: none;
        background: transparent;  /* 设置固定的背景颜色 */
        width: 10px;          /* 设置固定宽度 */
        margin: 0px;
    }

    QScrollBar::handle:vertical {
        background: transparent;
        height: 50px;
        min-height: 50px;
        max-height: 50px;
        border-radius: 5px;
    }

    QScrollBar::add-line:vertical,
    QScrollBar::sub-line:vertical {
        height: 0px;          /* 隐藏上下箭头 */
    }

    QScrollBar::add-page:vertical,
    QScrollBar::sub-page:vertical {
        background: none;
    }
    QScrollBar:horizontal {height: 0px;}
)");



    // 2. 创建核⼼ Widget
    container = new QWidget(this);
    container->setFixedWidth(210);
    this->setWidget(container);

    // 3. 创建布局
    QVBoxLayout* layout = new QVBoxLayout();
    layout->setContentsMargins(0, 0, 0, 0);
    layout->setSpacing(0);
    layout->setAlignment(Qt::AlignTop);
    container->setLayout(layout);

    //测试滚动效果
    // for (int i = 0; i < 50; i++) {
    //     QPushButton* btn = new QPushButton("hello button");
    //     layout->addWidget(btn);
    //     LOG() << "---> " << i;
    // }
}

void SessionFriendArea::clear()
{
    QLayout* layout = container->layout();
    // 从后往前遍历. 否则删除前⾯的元素会影响后⾯元素的下标
    for (int i = layout->count() - 1; i >= 0; i--) {
        QLayoutItem* item = layout->takeAt(i);
        if (item->widget()) {
            delete item->widget();
        }
        delete item;
    }
}

void SessionFriendArea::addItem(ItemType itemType, const QString &id, const QIcon &avatar, const QString &name, const QString &text)
{
    SessionFriendItem* itemWidget = nullptr;
    if (itemType == FriendItemType) {
        itemWidget = new FriendItem(this, id, avatar, name, text);
    } else if (itemType == SessionItemType) {
        itemWidget = new SessionItem(this, id, avatar, name, text);
    } else if (itemType == ApplyItemType) {
        itemWidget = new ApplyItem(this, id, avatar, name);
    }
    // 添加到 container 中
    container->layout()->addWidget(itemWidget);
}

void SessionFriendArea::clickItem(int index)
{
    if (index >= container->layout()->count()) {
        qCritical() << TAG << "点击的元素下标超出范围! index=" << index;
        return;
    }
    QLayoutItem* top = container->layout()->itemAt(index);
    if (top->widget() == nullptr) {
        qCritical() << TAG << "指定元素不存在! index=" << index;
        return;
    }
    SessionFriendItem* item = dynamic_cast<SessionFriendItem*>(top->widget());
    item->select();
}

bool SessionFriendArea::eventFilter(QObject *watched, QEvent *event)
{
    //当鼠标进入到该区域或滚动条区域时，显示滑块，否则隐藏
    if (watched == this->viewport()|| watched == this->verticalScrollBar()){
        {
            switch (event->type()) {
            case QEvent::Enter:
                // 鼠标进入Viewport或滚动条区域
                //设置滚动条样式
                this->verticalScrollBar()->setStyleSheet(R"(
                QScrollBar:vertical {
                    border: none;
                    background: transparent;  /* 设置固定的背景颜色 */
                    width: 10px;          /* 设置固定宽度 */
                    margin: 0px;
                }

                QScrollBar::handle:vertical {
                    background: #c0c0c0;
                    height: 50px;
                    min-height: 50px;
                    max-height: 50px;
                    border-radius: 5px;
                }

                QScrollBar::add-line:vertical,
                QScrollBar::sub-line:vertical {
                    height: 0px;          /* 隐藏上下箭头 */
                }

                QScrollBar::add-page:vertical,
                QScrollBar::sub-page:vertical {
                    background: transparent;
                }
                QScrollBar:horizontal {height: 0px;}

             )");
                break;
            case QEvent::Leave:
                // 鼠标离开Viewport或滚动条区域
                this->verticalScrollBar()->setStyleSheet(R"(
                QScrollBar:vertical {
                    border: none;
                    background: transparent;  /* 设置固定的背景颜色 */
                    width: 10px;          /* 设置固定宽度 */
                    margin: 0px;
                }

                QScrollBar::handle:vertical {
                    background: transparent;
                    height: 50px;
                    min-height: 50px;
                    max-height: 50px;
                    border-radius: 5px;
                }

                QScrollBar::add-line:vertical,
                QScrollBar::sub-line:vertical {
                    height: 0px;          /* 隐藏上下箭头 */
                }

                QScrollBar::add-page:vertical,
                QScrollBar::sub-page:vertical {
                    background: transparent;
                }
                QScrollBar:horizontal {height: 0px;}

             )");
                break;
            default:
                break;
            }
        }
    }

    return QObject::eventFilter(watched, event); // 调用基类的事件过滤器
}

///////////////////////////////////
////SessionFriendItem的实现
//////////////////////////////////

SessionFriendItem::SessionFriendItem(QWidget *owner, const QIcon &avatar, const QString &name, const QString &lastMessage)
{
    this->selected = false;
    //this->setStyleSheet("QWidget {background-color: rgb(231, 230, 229);}");
    this->setFixedHeight(70);
    layout = new QGridLayout();
    layout->setContentsMargins(10, 0, 0, 0);
    layout->setHorizontalSpacing(10);
    layout->setVerticalSpacing(0);
    this->setLayout(layout);

    // 创建头像
    QPushButton* avatarBtn = new QPushButton();
    avatarBtn->setFixedSize(40, 40);
    avatarBtn->setIcon(avatar);
    avatarBtn->setIconSize(QSize(40, 40));
    avatarBtn->setStyleSheet("QPushButton {background-color: #f7f7f7;}");
    avatarBtn->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);

    // 创建名字
    QLabel* nameLabel = new QLabel();
    nameLabel->setText(name);
    nameLabel->setStyleSheet("QLabel { font-size: 15px; font-weight: 450; }");
    nameLabel->setAlignment(Qt::AlignBottom); // 调整下⽂字对⻬位置, 看起来更好看⼀ 些.
    nameLabel->setFixedHeight(35);
    nameLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);

    // 创建消息预览
    messageLabel = new QLabel();
    messageLabel->setText(lastMessage);
    messageLabel->setFixedHeight(35);
    messageLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);

    layout->addWidget(avatarBtn, 0, 0, 2, 2);
    layout->addWidget(nameLabel, 0, 2, 1, 8);
    layout->addWidget(messageLabel, 1, 2, 1, 8);
}

void SessionFriendItem::mousePressEvent(QMouseEvent *event)
{
    (void) event;
    select();
}

void SessionFriendItem::select()
{
    // 清空其他兄弟元素的样式
    const QObjectList& children = this->parentWidget()->children();
    for (QObject* child : children) {
        if (!child->isWidgetType()) {
            // 不是 QWidget 直接跳过.
            continue;
        }

        SessionFriendItem* widget = dynamic_cast<SessionFriendItem*>(child);
        widget->selected = false;
        widget->setStyleSheet("QWidget {background-color: #f7f7f7;}");
    }

    // 应⽤⾃⼰的样式.
    this->setStyleSheet("QWidget { background-color: #D3D3D3; }");
    this->selected = true;

    // TODO 进⼀步的加载详情. 按照多态的⽅式调⽤到对应⼦类的 active
    this->active();

}

void SessionFriendItem::enterEvent(QEnterEvent *event)
{
    (void) event;
    if (!this->selected) {
        this->setStyleSheet("QWidget { background-color: #EAEAEA;}");
    }
}

void SessionFriendItem::leaveEvent(QEvent *event)
{
    (void) event;
    if (!this->selected) {
        this->setStyleSheet("QWidget {background-color: #f7f7f7;}");
    }
}

void SessionFriendItem::paintEvent(QPaintEvent *event)
{
    // 这⾥是官⽅⽂档给出的要求. 原因在⽂档上没有解释.
    (void) event;
    QStyleOption opt;
    opt.initFrom(this);
    QPainter p(this);
    style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
}

SessionItem::SessionItem(QWidget *owner, const QString &chatSessionId, const QIcon &avatar, const QString &name, const QString &lastMessage)
    : SessionFriendItem(owner, avatar, name, lastMessage),chatSessionId(chatSessionId)
{

    //绑定信号槽
    model::DataCenter* dataCenter = model::DataCenter::getInstance();

    connect(dataCenter, &model::DataCenter::updateLastMessage, this, &SessionItem::updateLastMessage);

    //构造的时候先获取一下未读消息
    int unread = dataCenter->getUnread(chatSessionId);
    if (unread > 0) {
        this->messageLabel->setText(QString("[未读%1条] ").arg(unread) + lastMessage);
    }

}

void SessionItem::active()
{
    LOG() << "SessionItem active. chatSessionId=" << chatSessionId;

    //清空未读消息
    //如果是消息列表可能还没加载, 直接清空原来⽂本内容中的 "未读x条"
    QString text = messageLabel->text();
    static QRegularExpression reg(R"(\[\S+\])");
    messageLabel->setText(text.replace(reg, ""));

    model::DataCenter* dataCenter = model::DataCenter::getInstance();
    dataCenter->clearUnread(chatSessionId);

    //加载当前会话的聊天内容
    MainWidget* widget = MainWidget::getInstance();
    widget->loadRecentMessages(chatSessionId);
}

void SessionItem::updateLastMessage(const QString &chatSessionId)
{
    //如果发来的信号的会话不是这个item当前的会话，就跳过
    if(this->chatSessionId != chatSessionId){
        return;
    }

    //获取最近一条消息
    model::DataCenter* dataCenter = model::DataCenter::getInstance();
    QList<model::Message>* messages = dataCenter->getRecentMessages(chatSessionId);
    if(messages == nullptr || messages->size() == 0){
        return;
    }

    model::Message lastMessage = messages->back();

    //确定显示的内容
    QString text;
    if (lastMessage.messageType == model::TEXT_TYPE) {
        text = lastMessage.content;
    } else if (lastMessage.messageType == model::IMAGE_TYPE) {
        text = "[图⽚]";
    } else if (lastMessage.messageType == model::FILE_TYPE) {
        text = "[⽂件]";
    } else if (lastMessage.messageType == model::SPEECH_TYPE) {
        text = "[语⾳]";
    } else {
        text = "[未知类型消息]";
    }

    //显示文本
    if(chatSessionId != dataCenter->getCurrentChatSessionId()){
        // 当前会话不是正在选中的会话, 写⼊未读消息数⽬
        int unreadCount = dataCenter->getUnread(chatSessionId);
        this->messageLabel->setText(QString("[未读%1条] ").arg(unreadCount) + text);
    }
    else {
        // 是正在选中的会话, 不需要写⼊未读消息数⽬
        this->messageLabel->setText(text);
    }
}

FriendItem::FriendItem(QWidget *owner, const QString &friendId, const QIcon &avatar, const QString &name, const QString &description)
    : SessionFriendItem(owner, avatar, name, description),userId(friendId)
{}

void FriendItem::active()
{
    LOG() << "FriendItem active. userId=" << userId;

    MainWidget* widget = MainWidget::getInstance();
    widget->switchToSession(userId);
}

ApplyItem::ApplyItem(QWidget *owner, const QString &userId, const QIcon &avatar, const QString &name)
    : SessionFriendItem(owner, avatar, name,""),userId(userId)
{
    // 1. 移除 messageLabel
    layout->removeWidget(messageLabel);
    messageLabel->deleteLater();

    // 2. 创建两个按钮
    QPushButton* acceptBtn = new QPushButton();
    acceptBtn->setText("同意");
    QPushButton* rejectBtn = new QPushButton();
    rejectBtn->setText("拒绝");
    // 3. 添加到布局中
    // layout->addWidget(messageLabel, 1, 2, 1, 8);
    layout->addWidget(acceptBtn, 1, 2, 1, 2);
    layout->addWidget(rejectBtn, 1, 4, 1, 2);


    connect(acceptBtn, &QPushButton::clicked, this, &ApplyItem::acceptFriend);
    connect(rejectBtn, &QPushButton::clicked, this, &ApplyItem::rejectFriend);
}

void ApplyItem::active()
{
    LOG() << "ApplyItem active.";
}

void ApplyItem::acceptFriend()
{
    model::DataCenter* dataCenter = model::DataCenter::getInstance();
    // 1. 设置回调
    connect(dataCenter, &model::DataCenter::acceptFriendApplyDone, this, &ApplyItem::acceptFriendDone, Qt::UniqueConnection);
    // 2. 发送⽹络请求, 同意好友申请
    dataCenter->acceptFriendApplyAsync(this->userId);
}

void ApplyItem::acceptFriendDone(const QString& userId, const QString& reason)
{
    // 1. 同意的不是当前的选项, 直接跳过
    if (userId != this->userId) {
        return;
    }
    // 2. 删除当前元素
    QWidget* parent = this->parentWidget();
    parent->layout()->removeWidget(this);

    // 3. 进⾏全局通知
    if (reason.isEmpty()) {
        LOG() << "好友申请接受成功!";
    } else {
        LOG() << "好友申请接受失败!" + reason;
    }

    // 4. 释放当前对象
    this->deleteLater();
}

void ApplyItem::rejectFriend()
{
    model::DataCenter* dataCenter = model::DataCenter::getInstance();
    // 1. 设置回调
    connect(dataCenter, &model::DataCenter::rejectFriendApplyDone, this, &ApplyItem::rejectFriendDone, Qt::UniqueConnection);
    // 2. 发送⽹络请求, 拒绝好友申请
    dataCenter->rejectFriendApplyAsync(this->userId);
}

void ApplyItem::rejectFriendDone(const QString &userId, const QString &reason)
{
    // 1. 同意的不是当前的选项, 直接跳过
    if (userId != this->userId) {
        return;
    }
    // 2. 删除当前元素
    QWidget* parent = this->parentWidget();
    parent->layout()->removeWidget(this);

    // 3. 进⾏全局通知
    if (reason.isEmpty()) {
        LOG() << "好友申请已拒绝!";
    } else {
        LOG() << "好友申请拒绝失败!" + reason;
    }

    // 4. 释放对象
    this->deleteLater();
}
